package cn.niit.config;

import cn.niit.entity.SysUser;
import cn.niit.service.SysResourceService;
import cn.niit.service.SysRoleService;
import cn.niit.service.SysUserService;
import cn.niit.utils.SaltUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Set;

/**
 * 自定义 Realm，主要为认证、授权提供数据源
 */
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SysResourceService resourceService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("UserRealm.doGetAuthorizationInfo ...................... 用户授权.............");
        String principal = (String) principalCollection.getPrimaryPrincipal();  //用户登录账号
        // TODO 根据用户账号从数据库中查询用户所拥有的角色、权限。
        //给资源进行授权
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //添加资源的授权字符串
        //判断登录用户的身份
        /*if("admin".equals(principal)){
            authorizationInfo.addRole("admin");
            authorizationInfo.addStringPermission("sys:user:*");
            authorizationInfo.addStringPermission("sys:role:*");
            authorizationInfo.addStringPermission("sys:permission:*");
            authorizationInfo.addStringPermission("sys:dict:*");
        } else if("wangwu".equals(principal)){
            authorizationInfo.addRole("teacher");
            authorizationInfo.addStringPermission("sys:user:select");
        } else {
            authorizationInfo.addRole("student");
            authorizationInfo.addStringPermission("user:select:user1");
        }*/
        /** TODO 第 1 步：由数据库查询该用户角色，并进行授权 */
        Set<String> roles = roleService.getRolesByUserCode(principal);
        authorizationInfo.setRoles(roles);

        /** TODO 第 2 步：由数据库查询该用户权限，并进行授权 */
        Set<String> permissions = resourceService.getPermissionsByUserCode(principal);
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }

    /**
     * 认证
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("UserRealm.doGetAuthenticationInfo ...................... 用户登录认证.............");
        String principal = (String) token.getPrincipal();
        System.out.println("principal = " + principal);
        //模拟：TODO 根据账号从数据库中查询用户记录
        /**
         * 123456 加密后：e10adc3949ba59abbe56e057f20f883e
         * 123456 使用 盐（Salt*1）加密后：a6ba7e57aa3374bb8b95cdffb100309d
         * 123456 使用 盐（Salt*1） 散列 1024 次，加密后：5bd90f07d40e99aea9ba290892ef9f6a
         */
        /*if("zhangsan".equals(principal)){
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, "5bd90f07d40e99aea9ba290892ef9f6a", ByteSource.Util.bytes("Salt*1"), this.getName());
            return info;
        }*/
        SysUser sysUser = sysUserService.selectByUserCode(principal);
        if(null != sysUser){
            String password = sysUser.getPassword();
            String salt = SaltUtils.PUBLIC_SALT + sysUser.getUserSalt();
            //SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, password, ByteSource.Util.bytes(salt), this.getName());
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, password, new MyByteSource(salt), this.getName());
            return info;
        }
        return null;
    }
}
